﻿using Inovout.Models;
using Microsoft.Data.Edm;
using Microsoft.Data.Edm.Library;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.OData.Builder;

namespace Inovout.Cloud.Web.OData
{
    public class ODataModelHelper
    {
        private static EdmModel model = new EdmModel();

        public static IEdmModel GetEdmModel(IQueryable query)
        {
            if (query == null)
            {
                return null;
            }

            var modelBuilder = new ODataConventionModelBuilder();
            modelBuilder.AddEntity(query.ElementType);
            return modelBuilder.GetEdmModel();
        }

        public static IEdmModel GetEdmModel(DataStructuralObject dataObject, string nameSpace)
        {
            EdmEntityType entityType = new EdmEntityType(nameSpace, dataObject.Name);

            if (dataObject.DataStructuralProperties != null)
            {
                IDictionary<string, Type> fields = dataObject.DataStructuralProperties.ToDictionary(x => x.Name, x => x.Type);

                 foreach (KeyValuePair<string, Type> kvp in fields)
                 {
                     entityType.AddStructuralProperty(kvp.Key, GetPropertyTypeKind(kvp.Value));
                 }
            }

            if (!model.SchemaElements.Contains(entityType))
            {
                model.AddElement(entityType);
            }

            return model;
        }

        /// <summary>
        /// 取得属性的类型
        /// </summary>
        /// <param name="type">类型</param>
        /// <returns></returns>
        private static EdmPrimitiveTypeKind GetPropertyTypeKind(Type type)
        {
            switch (type.FullName)
            {
                case "System.Boolean":
                    return EdmPrimitiveTypeKind.Boolean;
                case "System.Byte":
                    return EdmPrimitiveTypeKind.Byte;
                case "System.DateTime":
                    return EdmPrimitiveTypeKind.DateTime;
                case "System.DateTimeOffset":
                    return EdmPrimitiveTypeKind.DateTimeOffset;
                case "System.Decimal":
                    return EdmPrimitiveTypeKind.Decimal;
                case "System.Double":
                    return EdmPrimitiveTypeKind.Double;
                case "System.Guid":
                    return EdmPrimitiveTypeKind.Guid;
                case "System.Int16":
                    return EdmPrimitiveTypeKind.Int16;
                case "System.Int32":
                    return EdmPrimitiveTypeKind.Int32;
                case "System.Int64":
                    return EdmPrimitiveTypeKind.Int64;
                case "System.SByte":
                    return EdmPrimitiveTypeKind.SByte;
                case "System.Single":
                    return EdmPrimitiveTypeKind.Single;
                case "System.String":
                    return EdmPrimitiveTypeKind.String;
                default:
                    return EdmPrimitiveTypeKind.None;
            }
        }
    }
}
